﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CSharpTest.Net.Collections;
using CSharpTest.Net.Serialization;
using System.Collections;

namespace TEAA
{
    public class IndexManager
    {

        private static IndexManager indexManager;

        private Dictionary<string, Index<bool>> activeBoolIndexes;
        private Dictionary<string, Index<int>> activeIntIndexes;
        private Dictionary<string, Index<double>> activeDoubleIndexes;
        private Dictionary<string, Index<char>> activeCharIndexes;
        private Dictionary<string, Index<string>> activeStringIndexes;
        private Dictionary<string, Index<DateTime>> activeDateTimeIndexes;

        private IndexManager()
        {
            activeBoolIndexes = new Dictionary<string,Index<bool>>();
            activeIntIndexes = new Dictionary<string,Index<int>>();
            activeDoubleIndexes = new Dictionary<string,Index<double>>();
            activeCharIndexes = new Dictionary<string, Index<char>>();
            activeStringIndexes = new Dictionary<string,Index<string>>();
            activeDateTimeIndexes = new Dictionary<string,Index<DateTime>>();
        }

        public static IndexManager GetIndexManager()
        {
            if (indexManager == null)
                indexManager = new IndexManager();
            return indexManager;
        }

        public void CreateIndex<T>(String indexPath, IndexType indexType)
        {
            Index<T> index = null;

            switch (indexType)
            {
                case IndexType.BPlusTree:
                    index = new BPlusTreeIndex<T>(indexPath);
                    break;
            }

            TypeCode typeCode = Type.GetTypeCode(typeof(T));
            switch (typeCode)
            {
                case TypeCode.Boolean:
                    activeBoolIndexes.Add(indexPath, (Index<bool>)index);
                    break;

                case TypeCode.Int32:
                    activeIntIndexes.Add(indexPath, (Index<int>)index);
                    break;

                case TypeCode.Double:
                    activeDoubleIndexes.Add(indexPath, (Index<double>)index);
                    break;

                case TypeCode.Char:
                    activeCharIndexes.Add(indexPath, (Index<char>)index);
                    break;

                case TypeCode.String:
                    activeStringIndexes.Add(indexPath, (Index<string>)index);
                    break;

                case TypeCode.DateTime:
                    activeDateTimeIndexes.Add(indexPath, (Index<DateTime>)index);
                    break;
            }
        }

        public Index<T> GetIndex<T>(String indexPath)
        {
            TypeCode typeCode = Type.GetTypeCode(typeof(T));
            switch (typeCode)
            {
                case TypeCode.Boolean:
                    return (Index<T>) activeBoolIndexes[indexPath];

                case TypeCode.Int32:
                    return (Index<T>)activeIntIndexes[indexPath];

                case TypeCode.Double:
                    return (Index<T>)activeDoubleIndexes[indexPath];

                case TypeCode.Char:
                    return (Index<T>)activeCharIndexes[indexPath];

                case TypeCode.String:
                    return (Index<T>)activeStringIndexes[indexPath];

                case TypeCode.DateTime:
                    return (Index<T>)activeDateTimeIndexes[indexPath];
            }

            return default(Index<T>);
        }

        public void RemoveIndex<T>(String indexPath)
        {
            TypeCode typeCode = Type.GetTypeCode(typeof(T));
            switch (typeCode)
            {
                case TypeCode.Boolean:
                    activeBoolIndexes.Remove(indexPath);
                    break;

                case TypeCode.Int32:
                    activeIntIndexes.Remove(indexPath);
                    break;

                case TypeCode.Double:
                    activeDoubleIndexes.Remove(indexPath);
                    break;

                case TypeCode.Char:
                    activeCharIndexes.Remove(indexPath);
                    break;

                case TypeCode.String:
                    activeStringIndexes.Remove(indexPath);
                    break;

                case TypeCode.DateTime:
                    activeDateTimeIndexes.Remove(indexPath);
                    break;
            }
        }

    }
}
